/*
 * MiddlewareCommon.h
 *
 */

//FIXME deberíamos splitear esto en varios archivos para no mezclar todo. Pero por ahora dejémoslo así (Gonza)

#ifndef MIDDLEWARECOMMON_H_
#define MIDDLEWARECOMMON_H_

#include <iostream>
#include <list>
#include <map>
#include <vector>
#include "../common/IPCUids.h"

#define UNDEFINED_ID_PRODUCTO -1
#define UNDEFINED_ID_COMPRA -1

/* Canastos stuff */
#define MAX_PIEZAS 10
#define MAX_CANASTOS 50

/* R5 stuff */
#define R5_PEDIDOS_PENDIENTES_CANASTOS 0
#define R5_PEDIDOS_PENDIENTES_CINTAS 1
#define R5_PEDIDOS_PENDIENTES_PROD 2
#define R5_PEDIDOS_PENDIENTES_RECEPCION_CANASTOS 3 //adp a r5


#define R5_TIPO_PEDIDO_CANASTO 1
#define R5_TIPO_RECEPCION_CANASTO 1 
#define R5_TIPO_PRODUCCION 1 
#define R5_TIPO_CINTAS 1 

#define R5_AGV_INTERCAMBIO_IZQ 1
#define R5_AGV_INTERCAMBIO_MID 2
#define R5_AGV_INTERCAMBIO_DER 3

#define R5_ESTADO_DURMIENDO 0
#define R5_ESTADO_ACTIVO 1

//For data alignment purposes (32/64 bit compatibility)
#pragma pack(push, 1)


typedef int TipoPieza;
typedef int TipoProducto;
typedef int ProductoId;
typedef int OrdenCompraId;
typedef enum{PRODUCTO_TERMINADO=0, PRODUCTO_ROTO, PRODUCTO_EN_PRODUCCION}EstadoProducto;

struct OrdenCompraHeader
{
	OrdenCompraId ordenCompraId;
	int vendedorId;
	int clientId;

	OrdenCompraHeader():ordenCompraId(UNDEFINED_ID_COMPRA),vendedorId(-1),clientId(-1)
	{

	};

	bool operator<(const OrdenCompraHeader &a)const
	{
		return true;
	}
};

struct ProductoCantidad
{
	TipoProducto tipo;
	int cantidad;
};

struct Producto
{
	ProductoId productoId;
	TipoProducto tipo;
	EstadoProducto estado;
};

typedef std::map<TipoProducto,int> ProductoCantidadMap;
typedef std::list<ProductoCantidad> ProductoCantidadList;
typedef std::list<Producto> ProductoList;

//Nota: tiene una lista, nunca pasar por mq
struct OrdenCompra
{
	OrdenCompraHeader header;
	ProductoCantidadList productos;
};

/* Definiciones para Robot 5 */

typedef int EstadoRobot5;

typedef struct PendientesRobot5 {
	int contador[4];
} tPedidosDel5;

typedef struct PedidoCanasto {
	int idPieza;
	int idAgv;
} tPedidoCanastos5;


/* Definiciones para AGV */
// Cada posicion debe contener el id del tipo de pieza, o 0 si no es requerido
typedef struct PedidoPiezas {
	TipoPieza piezas[MAX_PIEZAS];
} tPedidoPiezas;

typedef struct Canasto {
	int idPieza;
	int cantidad;
	int uso; // cada robot que lo usa incrementa en 1 (max 2)
	int idAGV;   
} tCanasto;

typedef struct EstadoCanasto {
	bool estaVacio;
	bool ausente;
	int posicion;
} EstadoCanasto;

//Es una mem por sector: izquierdo, medio y derecho
typedef struct MemCanastos {
	Canasto canastos[50];
	int canastoDeEspera1; // Si es izq o der, corresponde al robot 11, si no, a uno de los 12.
	int canastoDeEspera2; // Solo si es central, corresponde al otro 12.
} tMemoriaCanastos;

typedef struct PedidoCintas {
	int a;
	int id;
} tPedidoCintas;

typedef struct PedidoProduccion {
	int b;
	int tipoProducto;
	int cantidad;
} tPedidoProduccion;

typedef struct PedidoGabinetes {
	int c;
}tPedidoGabinetes;

// Cintas

typedef struct CintaProductos{
	Producto productos[5];
	bool vacios[5];
} CintaProductos;

#pragma pack(pop)


#endif /* MIDDLEWARECOMMON_H_ */
